package com.zengdb.jdbc.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/*
 * 原生数据库连接jdbc工具类，负责获得数据库连接和释放连接资源，以及事务的开启、提交 、回滚操作
 * 当前工具类的事务操作只适合在单线程使用，在多线程操作事务使用工具类DataSourceJdbcUtil
 */
public class JdbcUtil {

	private static String driverClassName = "com.mysql.jdbc.Driver";
	private static String url = "jdbc:mysql:///jdbcdemo";
	private static String username = "root";
	private static String password = "admin";

	private static Connection conn; //当conn不为Null时，则存在事务。当存在事务时，在事务提交或回滚事务时，关闭连接对象
	

	public static Connection getConn() {
		return conn;
	}

	static {
		try {
			//加载驱动
			Class.forName(driverClassName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	//工具类构造方法私有，禁止外部创建当前类的实例
	private JdbcUtil() {
	}
	
	/**
	 * 获取数据库连接
	 *判断conn是否为null，如果为null说明没有事务，那么返回一个新的连接；
	 *如果不为null，说明已经开始了事务，那么直接返回conn。当conn不为null时，无论调用多少次getConnection()方法，返回的都是同个Connection对象。
	 * @return 返回数据库连接对象
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException {
		return conn == null ? DriverManager.getConnection(url, username, password) : conn;
	}

	/**
	 * 
	 *判断conn是否为null，如果不为null，就抛出"事务已经开启"异常！
	 *如果conn为null，那么返回一个新的连接Connection对象，赋值给conn！然后设置它为“手动提交”。
	 * @throws SQLException
	 */
	public static void beginTransaction() throws SQLException {
		if (conn != null) {
			throw new SQLException("事务已经开启，在没有结束当前事务时，不能再开启事务！");
		}
		conn = getConnection();
		conn.setAutoCommit(false);
	}

	/**
	 * 
	 *判断conn是否为null，如果为null，说明没有开启事务就提交事务，那么抛出异常；
	 *如果conn不为null，那么调用conn的commit()方法来提交事务；
	 *调用con.close()方法关闭连接；
	 *conn = null，这表示事务已经结束！
	 * @throws SQLException
	 */
	public static void commitTransaction() throws SQLException {
		if (conn == null) {
			throw new SQLException("当前没有事务，不能提交事务！");
		}
		conn.commit();
		conn.close();
		conn = null;
	}

	/**
	 * 
	 *判断conn是否为null，如果为null，说明没有开启事务就回滚事务，那么抛出异常；
	 *如果conn不为null，那么调用conn的rollback()方法来回滚事务；
	 *调用con.close()方法关闭连接；
	 *conn = null，这表示事务已经结束！
	 * @throws SQLException
	 */
	public static void rollbackTransaction() throws SQLException {
		if (conn == null) {
			throw new SQLException("当前没有事务，所以不能回滚事务！");
		}
		conn.rollback();
		conn.close();
		conn = null;
	}
	
	/**
	 *释放数据库连接资源 
	 * @param conn 数据库连接对象
	 * @param stat 执行数据库SQL语句的对象
	 * @param rs 执行SQL语名后退回的结果集对象
	 */
	public static void close(Connection conn, Statement stat, ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (stat != null) {
					stat.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
